package simplecontext

import (
	"context"
	"fmt"
	"log"
	"time"

	"golang.org/x/sync/errgroup"
)

func use_errgroup() {
	//设置超时时间为5s
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	//错误通道，用于传递任务错误
	errChan := make(chan error, 1)

	//创建errgroup用于管理任务和错误
	var g errgroup.Group

	//启动三个任务
	taskNames := []string{"task1", "task2", "task3"}
	for _, taskName := range taskNames {
		//将每个任务添加到errgroup
		taskName := taskName //在闭包中使用局部副本
		g.Go(func() error {
			return errgroup_monitorTask(ctx, taskName, errChan)
		})
	}

	//监听错误和完成状态
	go func() {
		select {
		case err := <-errChan:
			log.Printf("Error occurred: %v\n", err)
			cancel() //取消所有任务执行

		case <-ctx.Done(): //超时或手动取消
		}
	}()

	//等待所有任务完成或取消
	if err := g.Wait(); err != nil {
		log.Printf("Task execution error: %v\n", err)
	} else {
		log.Println("All tasks completed successfully")
	}

	//检查是否超时
	if ctx.Err() == context.DeadlineExceeded {
		log.Println("Tasks terminated due to timeout")
	} else {
		log.Println("All tasks completed or canceled")
	}
}

// 定义任务执行函数
func errgroup_monitorTask(ctx context.Context, name string, errChan chan error) error {
	//模拟任务执行
	select {
	case <-errChan:
		log.Printf("Task %s was canceled due to timeout or error:%v\n", name, ctx.Err())
		return ctx.Err()
	default:
		switch name {
		case "task1":
			time.Sleep(2 * time.Second)
			log.Printf("%v completed successfully\n", name)
			return nil
		case "task2":
			//err := errors.New(fmt.Sprintf("%s encountered an error", name))
			err := fmt.Errorf("%s encountered an error", name)
			errChan <- err
			log.Printf("%s encountered an error\n", name)
			return err
		case "task3":
			time.Sleep(4 * time.Second)
			if ctx.Err() == nil {
				log.Printf("%s completed successfully\n", name)
				return nil
			} else {
				log.Printf("%s was canceled due to timeout\n", name)
				return ctx.Err()
			}
		}
	}
	return nil
}
